/**
 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef PANDA_PROFILING_GEN_H
#define PANDA_PROFILING_GEN_H

#include "libpandafile/bytecode_instruction-inl.h"
#include <array>

namespace ark::profiling {

% require 'set'
% require_relative '../../templates/common.rb'

enum class ProfilingKind {
    NONE,
% Panda::profiles.each do |name, _|
    <%= name.snakecase.upcase %>,
% end
};

inline constexpr const char* GetProfilingKindName(ProfilingKind kind)
{
    // NOLINTNEXTLINE(hicpp-multiway-paths-covered)
    switch (kind) {
% Panda::profiles.each do |prof, _|
        case ProfilingKind::<%= prof.snakecase.upcase %>:
            return "<%= prof.snakecase.upcase %>";
% end
        default:
            return "INVALID";
    }
}

% sizes = Panda::profiles.values.map(&:size).uniq.sort
inline constexpr std::array<uint8_t, <%= sizes.size %>> GetOrderedProfileSizes() {
    return {<%= sizes.join(', ') %>};
}

inline size_t GetProfileSizeInBytes(BytecodeInstruction::Opcode opcode)
{
    // NOLINTNEXTLINE(hicpp-multiway-paths-covered)
    switch (opcode) {
% Panda::instructions.select { |x| x.profiled? }.each do |inst|
        case BytecodeInstruction::Opcode::<%= inst.opcode.upcase %>:
            return <%= inst.profile.size %>;
% end
        default:
            return 0;
    }
}

inline ProfilingKind GetProfileKind(BytecodeInstruction::Opcode opcode)
{
    // NOLINTNEXTLINE(hicpp-multiway-paths-covered)
    switch (opcode) {
% Panda::instructions.select { |x| x.profiled? }.each do |inst|
        case BytecodeInstruction::Opcode::<%= inst.opcode.upcase %>:
            return ProfilingKind::<%= inst.profile.name.snakecase.upcase %>;
% end
        default:
            return ProfilingKind::NONE;
    }
}

}  // namespace ark::profiling

#endif  // PANDA_PROFILING_GEN_H
